rime 输入法配置

23次阅读
没有评论

共计 10930 个字符,预计需要花费 28 分钟才能阅读完成。

为什么用 rime

在当今数字时代,大数据分析、广告联盟和精准营销已成为常态。然而,这些看似便利的技术背后,往往伴随着个人隐私的深度挖掘与潜在泄露。在众多可能导致隐私泄露的途径中,我们日常频繁使用的输入法无疑是其中一个重灾区。

以我个人为例,曾长期使用搜狗输入法。尽管我凭借一定的电脑使用经验,努力屏蔽了其大部分冗余功能和广告弹窗,但近期搜狗爆出的“云控下发模块”丑闻(火绒分析搜狗云控下发模块)彻底打破了这种“安全感”。这并非孤例。日常生活中,我们屡次发现,在输入某些关键词后,很快便能收到高度相关的精准推销广告;输入法读取剪切板的行为更是屡见不鲜。这些现象无不指向一个事实:我们的打字内容、复制粘贴信息等敏感数据,正被输入法厂商无底线地收集、分析乃至滥用。

诚然,云计算技术为输入法带来了便捷的云同步、词库更新等功能,但其背后却是用户数据的大量上传与潜在泄露。这种以牺牲隐私换取便利的做法,已让我无法接受。

在当前数字环境下,完全杜绝隐私泄露或许难以实现。然而,“往者不可谏,来者犹可追”,我们并非束手无策。面对厂商的无底线行为,我们至少可以选择主动出击,尽可能减少个人数据泄露的途径,重新审视并选择更注重隐私保护的工具。

在对主流输入法厂商的无底线行为感到失望之后,许多重视隐私的用户将目光投向了开源且高度可定制的 Rime输入法框架。Rime,在不同操作系统下有不同的前端名称,例如在Windows上常被称为“小狼毫”,在macOS上是“鼠鬚管”,而在Linux上则被称为“中州韵”。

Rime与我们之前讨论的那些主流输入法有着本质的区别:它的核心理念是“本地化”和“用户主导”。这意味着,Rime在设计之初就将用户隐私放在首位。它不上传任何用户数据到云端,没有所谓的“云同步”功能(除非用户自行配置第三方服务),更不会有广告推送或数据分析行为。你的输入习惯、词库、个人配置,都完全存储在本地设备上,数据的控制权牢牢掌握在你手中。这彻底避免了因云端数据泄露或厂商滥用数据而带来的隐私风险。

Rime的另一个显著特点是其极高的可定制性。它提供了一个高度灵活的配置系统,允许用户从输入方案、词库、按键布局到界面主题,进行几乎无限制的个性化设置。这与那些功能臃肿、广告缠身、且用户无权干预的商业输入法形成了鲜明对比,真正实现了“我的输入法我做主”。

当然,这种极致的自由和隐私保护并非没有代价。Rime的上手门槛相对较高,初次配置可能需要投入一定的时间和精力去学习其配置文件和逻辑。但对于那些真正重视数据安全、厌倦了被厂商“喂养”的用户而言,这无疑是一笔值得的投资。它不仅仅是一个输入法,更是一种对个人数据主权和数字自由的坚守。

我日常使用的平台是:Windows + Android,下文会基于此介绍我的配置方案。

Windows:小狼毫

Android:雨燕输入法

Windows配置

下载安装

下载链接:小狼毫官网

安装过程不赘述,一路点击即可。

用户数据路径为:%APPDATA%\Rime

主题配置

个人习惯 微软输入法 的主题风格,修改 用户数据路径 下的 weasel.custom.yaml​:

patch: 
  preset_color_schemes: 
    microsoft_sim: 
      name: 仿微软输入法
      author: plutotree
      back_color: 0xF4F4F4
      border_color: 0xDCDCDC
      text_color: 0x000000
      hilited_text_color: 0xF4F4F4
      hilited_back_color: 0xFFD8A6
      hilited_candidate_text_color: 0x000000
      hilited_candidate_back_color: 0xFFD8A6
      candidate_text_color: 0x000000
      comment_text_color: 0x888888

  style: 
    color_scheme: microsoft_sim
    label_format: "%s" 
    font_face: "微软雅黑" 
    font_point: 13
    horizontal: false
    inline_preedit: true
    layout: 
      min_width: 140
      min_height: 0
      border_width: 1
      border_height: 1
      margin_x: 9
      margin_y: 9
      spacing: 5
      candidate_spacing: 0
      hilite_spacing: 7
      hilite_padding: 2
      round_corner: 0

第三方词库配置

默认词库并不好用,选用白霜词库:白霜拼音

下载后,将文件复制到用户数据路径:%APPDATA%\Rime
rime 输入法配置

输入法设定​中,启用白霜词库,选择访微软风格皮肤:
rime 输入法配置

rime 输入法配置

个人历史词库导入

从搜狗输入法PC端导出用户词库bin文件:
rime 输入法配置

下载深蓝词库转换,将搜狗bin词库,转换为 rime中州韵 词库txt文件:
rime 输入法配置

在小狼毫用户词典管理导入txt:
rime 输入法配置

PC端同步

需要自行架设webdav服务,可参考站内文章:webdav 部署和使用

修改设备ID和同步路径,修改 用户数据路径 下的:installation.yaml

# 增加两行
installation_id: "HD-WORK-WIN-1"
sync_dir: "X:/rime-sync"

手动同步,同步完后点击重新部署:

rime 输入法配置

自动同步可通过编写同步脚本和添加任务计划程序,可参考:我的rime:打造多端同步的本地输入法

移动端

移动端下有3个基于 rime框架 的输入法,可参考:手机输入法使用体验

我选择了雨燕输入法,因为更简单,而且符合我之前的使用习惯。

安卓导入个人历史词库

雨燕输入法 没办法实现实时同步,因为它不直接兼容用户导入rime用户数据,有自己的导入导出解决方案。

我只期望将历史词库导入即可。

写了1个 python 脚本,用于合并存量个人词库。

先在安卓设备雨燕输入法上导出用户数据ZIP包:

rime 输入法配置

windows10设备上已经导入好了词库,完整打包 用户数据路径下的 rime_frost.userdb​ 目录:

需要注意复制前要彻底关闭小狼毫,否则文件被占用无法执行读取操作。

最简单的方式是卸载程序。卸载不会对用户数据路径做变更,待复制完毕后再重新安装即可。
rime 输入法配置

将 雨燕输入法的ZIP包 和 小狼毫的数据目录 完整放置到Ubuntu服务器上,添加如下脚本并执行(路径自行修改):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Rime词库合并工具 - 标准版
将小狼毫词库合并到雨燕词库中,保留雨燕原有数据和元数据
"""

import plyvel
import zipfile
import os
import shutil
import time
import sys

# 配置变量
YUYAN_ORIGINAL_ZIP = "/ops/rime/yuyanIme_2025-09-25_09_05_00.zip"
XIAOLANGHAO_DB_PATH = "/ops/rime/rime_frost.userdb"
OUTPUT_ZIP = "/ops/rime/yuyan_merged_final.zip"
TEMP_DIR = "/ops/rime/temp_merge_final"
VERIFY_TEMP_DIR = "/ops/rime/temp_verify_final"

def print_step(step_num, total_steps, description):
    """标准化步骤输出"""
    print(f"[{step_num}/{total_steps}] {description}")

def print_info(message, indent=0):
    """标准化信息输出"""
    prefix = "  " * indent
    print(f"{prefix}INFO: {message}")

def print_stats(title, stats_dict, indent=0):
    """标准化统计信息输出"""
    prefix = "  " * indent
    print(f"{prefix}{title}:")
    for key, value in stats_dict.items():
        print(f"{prefix}  - {key}: {value}")

def analyze_database(db_path, db_name):
    """分析数据库内容并返回统计信息"""
    print_info(f"正在分析{db_name}数据库: {db_path}")

    try:
        db = plyvel.DB(db_path, create_if_missing=False)

        metadata = {}
        words = {}

        for key, value in db:
            if key.startswith(b'\x01/'):
                metadata[key] = value
            else:
                words[key] = value

        db.close()

        # 计算数据库文件大小
        total_size = 0
        if os.path.exists(db_path):
            for item in os.listdir(db_path):
                item_path = os.path.join(db_path, item)
                if os.path.isfile(item_path):
                    total_size += os.path.getsize(item_path)

        stats = {
            "元数据条目": len(metadata),
            "用户词条": len(words),
            "总记录数": len(metadata) + len(words),
            "数据库大小": f"{total_size / 1024:.1f} KB"
        }

        print_stats(f"{db_name}统计信息", stats, indent=1)

        return {
            "metadata": metadata,
            "words": words,
            "stats": stats,
            "total_size": total_size
        }

    except Exception as e:
        print(f"ERROR: 无法分析{db_name}数据库: {e}")
        return None

def extract_yuyan_zip():
    """解压雨燕ZIP包并分析内容"""
    print_info(f"解压雨燕ZIP包: {YUYAN_ORIGINAL_ZIP}")

    if os.path.exists(TEMP_DIR):
        shutil.rmtree(TEMP_DIR)

    try:
        with zipfile.ZipFile(YUYAN_ORIGINAL_ZIP, 'r') as zipf:
            file_list = zipf.namelist()
            zipf.extractall(TEMP_DIR)

        print_info(f"ZIP包含文件数: {len(file_list)}")

        # 分析解压后的雨燕数据库
        yuyan_db_path = os.path.join(TEMP_DIR, "external/rime/pinyin.userdb")
        yuyan_data = analyze_database(yuyan_db_path, "雨燕")

        return file_list, yuyan_data

    except Exception as e:
        print(f"ERROR: 解压雨燕ZIP包失败: {e}")
        return None, None

def merge_databases(yuyan_data, xiaolanghao_data):
    """合并数据库内容"""
    print_info("开始合并数据库内容")

    # 从雨燕数据开始(包含元数据和词条)
    merged_data = yuyan_data["metadata"].copy()
    merged_data.update(yuyan_data["words"])

    # 统计信息
    original_word_count = len(yuyan_data["words"])
    xiaolanghao_word_count = len(xiaolanghao_data["words"])

    # 添加小狼毫词条(只添加雨燕没有的)
    added_count = 0
    duplicate_count = 0

    for key, value in xiaolanghao_data["words"].items():
        if key in merged_data:
            duplicate_count += 1
        else:
            merged_data[key] = value
            added_count += 1

    final_word_count = len([k for k in merged_data.keys() if not k.startswith(b'\x01/')])
    final_metadata_count = len([k for k in merged_data.keys() if k.startswith(b'\x01/')])

    merge_stats = {
        "雨燕原有词条": original_word_count,
        "小狼毫总词条": xiaolanghao_word_count,
        "重复词条": duplicate_count,
        "新增词条": added_count,
        "合并后词条总数": final_word_count,
        "元数据条目": final_metadata_count,
        "合并后总记录": len(merged_data)
    }

    print_stats("合并统计", merge_stats, indent=1)

    return merged_data, merge_stats

def rebuild_database(merged_data):
    """重建数据库"""
    print_info("重建数据库")

    new_db_path = os.path.join(TEMP_DIR, "external/rime/pinyin.userdb")

    # 删除旧数据库
    if os.path.exists(new_db_path):
        shutil.rmtree(new_db_path)
        print_info("已删除旧数据库文件", indent=1)

    try:
        # 创建新数据库
        new_db = plyvel.DB(new_db_path, create_if_missing=True)

        # 写入所有数据
        write_count = 0
        for key, value in merged_data.items():
            new_db.put(key, value)
            write_count += 1

            if write_count % 5000 == 0:
                print_info(f"已写入 {write_count} 条记录", indent=1)

        # 强制同步数据库
        new_db.close()
        time.sleep(2)  # 等待文件系统同步

        print_info(f"数据库重建完成,共写入 {write_count} 条记录", indent=1)

        # 验证重建后的数据库
        return verify_rebuilt_database(new_db_path, len(merged_data))

    except Exception as e:
        print(f"ERROR: 重建数据库失败: {e}")
        return False

def verify_rebuilt_database(db_path, expected_count):
    """验证重建后的数据库"""
    print_info("验证重建后的数据库", indent=1)

    try:
        # 检查文件大小
        total_size = 0
        db_files = []
        for item in os.listdir(db_path):
            item_path = os.path.join(db_path, item)
            if os.path.isfile(item_path):
                size = os.path.getsize(item_path)
                total_size += size
                db_files.append(f"{item}: {size} bytes")

        print_info(f"数据库文件: {len(db_files)} 个", indent=2)
        print_info(f"数据库总大小: {total_size / 1024:.1f} KB", indent=2)

        if total_size < 100000:  # 小于100KB可能有问题
            print("WARNING: 数据库大小异常小")
            return False

        # 验证数据可读性
        verify_db = plyvel.DB(db_path, create_if_missing=False)
        actual_count = 0
        for key, value in verify_db:
            actual_count += 1
        verify_db.close()

        print_info(f"验证记录数: {actual_count} (期望: {expected_count})", indent=2)

        if actual_count == expected_count:
            print_info("数据库验证成功", indent=2)
            return True
        else:
            print(f"ERROR: 记录数不匹配")
            return False

    except Exception as e:
        print(f"ERROR: 数据库验证失败: {e}")
        return False

def create_final_zip(file_list):
    """创建最终的ZIP包"""
    print_info(f"创建最终ZIP包: {OUTPUT_ZIP}")

    try:
        with zipfile.ZipFile(OUTPUT_ZIP, 'w', zipfile.ZIP_DEFLATED, compresslevel=6) as new_zip:
            for file_path in file_list:
                full_path = os.path.join(TEMP_DIR, file_path)

                if file_path == 'external/rime/pinyin.userdb/':
                    # 特殊处理数据库目录
                    db_dir = os.path.join(TEMP_DIR, 'external/rime/pinyin.userdb')
                    new_zip.writestr('external/rime/pinyin.userdb/', '')

                    db_file_count = 0
                    for db_file in sorted(os.listdir(db_dir)):
                        db_file_path = os.path.join(db_dir, db_file)
                        if os.path.isfile(db_file_path):
                            arc_path = f'external/rime/pinyin.userdb/{db_file}'
                            new_zip.write(db_file_path, arc_path)
                            db_file_count += 1

                    print_info(f"已添加数据库文件: {db_file_count} 个", indent=1)

                elif os.path.exists(full_path) and not file_path.startswith('external/rime/pinyin.userdb/'):
                    new_zip.write(full_path, file_path)

        zip_size = os.path.getsize(OUTPUT_ZIP)
        print_info(f"ZIP包创建完成,大小: {zip_size / 1024:.1f} KB", indent=1)

        return True

    except Exception as e:
        print(f"ERROR: 创建ZIP包失败: {e}")
        return False

def final_verification():
    """最终验证"""
    print_info("执行最终验证")

    if os.path.exists(VERIFY_TEMP_DIR):
        shutil.rmtree(VERIFY_TEMP_DIR)

    try:
        # 解压最终ZIP包
        with zipfile.ZipFile(OUTPUT_ZIP, 'r') as zipf:
            zipf.extractall(VERIFY_TEMP_DIR)

        # 验证数据库
        final_db_path = os.path.join(VERIFY_TEMP_DIR, "external/rime/pinyin.userdb")
        final_data = analyze_database(final_db_path, "最终")

        if final_data:
            print_info("最终验证成功", indent=1)
            return True
        else:
            print("ERROR: 最终验证失败")
            return False

    except Exception as e:
        print(f"ERROR: 最终验证失败: {e}")
        return False
    finally:
        if os.path.exists(VERIFY_TEMP_DIR):
            shutil.rmtree(VERIFY_TEMP_DIR)

def cleanup():
    """清理临时文件"""
    if os.path.exists(TEMP_DIR):
        shutil.rmtree(TEMP_DIR)
    if os.path.exists(VERIFY_TEMP_DIR):
        shutil.rmtree(VERIFY_TEMP_DIR)

def main():
    """主函数"""
    print("Rime词库合并工具 - 标准版")
    print("=" * 50)

    total_steps = 7

    try:
        # 步骤1: 解压并分析雨燕ZIP包
        print_step(1, total_steps, "解压并分析雨燕ZIP包")
        file_list, yuyan_data = extract_yuyan_zip()
        if not yuyan_data:
            return False

        # 步骤2: 分析小狼毫数据库
        print_step(2, total_steps, "分析小狼毫数据库")
        xiaolanghao_data = analyze_database(XIAOLANGHAO_DB_PATH, "小狼毫")
        if not xiaolanghao_data:
            return False

        # 步骤3: 合并数据库内容
        print_step(3, total_steps, "合并数据库内容")
        merged_data, merge_stats = merge_databases(yuyan_data, xiaolanghao_data)

        # 步骤4: 重建数据库
        print_step(4, total_steps, "重建数据库")
        if not rebuild_database(merged_data):
            return False

        # 步骤5: 创建最终ZIP包
        print_step(5, total_steps, "创建最终ZIP包")
        if not create_final_zip(file_list):
            return False

        # 步骤6: 最终验证
        print_step(6, total_steps, "最终验证")
        if not final_verification():
            return False

        # 步骤7: 清理临时文件
        print_step(7, total_steps, "清理临时文件")
        cleanup()

        print("=" * 50)
        print("合并完成!")
        print(f"输出文件: {OUTPUT_ZIP}")
        print("请将此文件导入到雨燕输入法")

        return True

    except Exception as e:
        print(f"ERROR: 合并过程失败: {e}")
        cleanup()
        return False

if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1)

执行后效果如下,将输出的包导入到雨燕输入法即可:

[root@ ubuntu-ops /ops/rime]
10:31:12 # python3 rime_yuyan_merge_xiaolanghao.py
Rime词库合并工具 - 标准版
==================================================
[1/7] 解压并分析雨燕ZIP包
INFO: 解压雨燕ZIP包: /ops/rime/yuyanIme_2025-09-25_09_05_00.zip
INFO: ZIP包含文件数: 66
INFO: 正在分析雨燕数据库: /ops/rime/temp_merge_final/external/rime/pinyin.userdb
  雨燕统计信息:
    - 元数据条目: 5
    - 用户词条: 387
    - 总记录数: 392
    - 数据库大小: 17.9 KB
[2/7] 分析小狼毫数据库
INFO: 正在分析小狼毫数据库: /ops/rime/rime_frost.userdb
  小狼毫统计信息:
    - 元数据条目: 5
    - 用户词条: 37171
    - 总记录数: 37176
    - 数据库大小: 1593.3 KB
[3/7] 合并数据库内容
INFO: 开始合并数据库内容
  合并统计:
    - 雨燕原有词条: 387
    - 小狼毫总词条: 37171
    - 重复词条: 128
    - 新增词条: 37043
    - 合并后词条总数: 37430
    - 元数据条目: 5
    - 合并后总记录: 37435
[4/7] 重建数据库
INFO: 重建数据库
  INFO: 已删除旧数据库文件
  INFO: 已写入 5000 条记录
  INFO: 已写入 10000 条记录
  INFO: 已写入 15000 条记录
  INFO: 已写入 20000 条记录
  INFO: 已写入 25000 条记录
  INFO: 已写入 30000 条记录
  INFO: 已写入 35000 条记录
  INFO: 数据库重建完成,共写入 37435 条记录
  INFO: 验证重建后的数据库
    INFO: 数据库文件: 5 个
    INFO: 数据库总大小: 2073.6 KB
    INFO: 验证记录数: 37435 (期望: 37435)
    INFO: 数据库验证成功
[5/7] 创建最终ZIP包
INFO: 创建最终ZIP包: /ops/rime/yuyan_merged_final.zip
  INFO: 已添加数据库文件: 7 个
  INFO: ZIP包创建完成,大小: 30499.6 KB
[6/7] 最终验证
INFO: 执行最终验证
INFO: 正在分析最终数据库: /ops/rime/temp_verify_final/external/rime/pinyin.userdb
  最终统计信息:
    - 元数据条目: 5
    - 用户词条: 37430
    - 总记录数: 37435
    - 数据库大小: 687.1 KB
  INFO: 最终验证成功
[7/7] 清理临时文件
==================================================
合并完成!
输出文件: /ops/rime/yuyan_merged_final.zip
请将此文件导入到雨燕输入法

总结

初次使用过程的确比较麻烦,特别是将历史词库导入到雨燕花费了我很大的精力。

跨设备的剪切板同步,我使用了 SyncClipboard,也是基于webdav实现。不过安卓设备要实现自动同步依赖获取 Root权限。

引用链接

正文完
 
pengyinwei
版权声明:本站原创文章,由 pengyinwei 2025-09-25发表,共计10930字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处:https://www.opshub.cn
评论(没有评论)